package maple.thelittleredbook.logging.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import maple.thelittleredbook.logging.entity.SysLog;
import maple.thelittleredbook.logging.mapper.SysLogMapper;

import java.time.LocalDateTime;

@Slf4j
@Service
public class SysLogService {

    private final SysLogMapper sysLogMapper;

    @Autowired
    public SysLogService(SysLogMapper sysLogMapper) {
        this.sysLogMapper = sysLogMapper;
    }

    /**
     * 异步保存系统日志
     *
     * @param sysLog 系统日志对象
     */
    @Async("logExecutor")
    public void saveLog(SysLog sysLog) {
        try {
            // 设置创建时间
            if (sysLog.getCreatedAt() == null) {
                sysLog.setCreatedAt(LocalDateTime.now());
            }

            // 截断过长的数据，防止数据库字段溢出
            truncateLogData(sysLog);

            // 保存到数据库
            sysLogMapper.insert(sysLog);

            log.debug("系统日志保存成功: operation={}, userId={}, costTime={}ms",
                    sysLog.getOperation(), sysLog.getUserId(), sysLog.getCostTime());
        } catch (Exception e) {
            // 日志保存失败不应该影响主业务，只记录错误信息
            log.error("保存系统日志失败: operation={}, error={}",
                    sysLog != null ? sysLog.getOperation() : "unknown", e.getMessage(), e);
        }
    }

    /**
     * 截断过长的日志数据
     *
     * @param sysLog 系统日志对象
     */
    private void truncateLogData(SysLog sysLog) {
        // 截断操作描述（最大50字符）
        if (sysLog.getOperation() != null && sysLog.getOperation().length() > 50) {
            sysLog.setOperation(sysLog.getOperation().substring(0, 50));
        }

        // 截断请求方法（最大200字符）
        if (sysLog.getMethod() != null && sysLog.getMethod().length() > 200) {
            sysLog.setMethod(sysLog.getMethod().substring(0, 200));
        }

        // 截断请求URL（最大255字符）
        if (sysLog.getRequestUrl() != null && sysLog.getRequestUrl().length() > 255) {
            sysLog.setRequestUrl(sysLog.getRequestUrl().substring(0, 255));
        }

        // 截断请求方式（最大10字符）
        if (sysLog.getRequestMethod() != null && sysLog.getRequestMethod().length() > 10) {
            sysLog.setRequestMethod(sysLog.getRequestMethod().substring(0, 10));
        }

        // 截断用户名（最大50字符）
        if (sysLog.getUsername() != null && sysLog.getUsername().length() > 50) {
            sysLog.setUsername(sysLog.getUsername().substring(0, 50));
        }

        // 截断请求IP（最大64字符）
        if (sysLog.getRequestIp() != null && sysLog.getRequestIp().length() > 64) {
            sysLog.setRequestIp(sysLog.getRequestIp().substring(0, 64));
        }

        // 截断请求参数（最大2000字符，避免TEXT字段过大）
        if (sysLog.getRequestParams() != null && sysLog.getRequestParams().length() > 2000) {
            sysLog.setRequestParams(sysLog.getRequestParams().substring(0, 2000) + "...[数据被截断]");
        }

        // 截断响应数据（最大2000字符，避免TEXT字段过大）
        if (sysLog.getResponseData() != null && sysLog.getResponseData().length() > 2000) {
            sysLog.setResponseData(sysLog.getResponseData().substring(0, 2000) + "...[数据被截断]");
        }
    }

    /**
     * 创建一个新的系统日志对象
     *
     * @return 新的SysLog对象
     */
    public SysLog createNewLog() {
        SysLog sysLog = new SysLog();
        sysLog.setCreatedAt(LocalDateTime.now());
        return sysLog;
    }
}